package com.corecloud.tools;

import com.alibaba.fastjson.JSONArray;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.apachecommons.CommonsLog;
import org.apache.http.HttpEntity;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.*;
import java.util.Map.Entry;


/**
 * HTTP请求工具类
 */
@CommonsLog
public class HttpUtil {


	public static String doGet(String url) {
		CloseableHttpClient httpClient = null;
		CloseableHttpResponse response = null;
		String result = "";
		try {
			// 通过址默认配置创建一个httpClient实例
			httpClient = HttpClients.createDefault();
			// 创建httpGet远程连接实例
			HttpGet httpGet = new HttpGet(url);
			// 设置请求头信息,鉴权
			httpGet.setHeader("Authorization", "Bearer da3efcbf-0845-4fe3-8aba-ee040be542c0");
			// 设置配置请求参数
			RequestConfig requestConfig = RequestConfig.custom().setConnectTimeout(35000)// 连接主机服务超时时间
					.setConnectionRequestTimeout(35000)// 请求超时时间
					.setSocketTimeout(60000)// 数据读取超时时间
					.build();
			// 为httpGet实例设置配置
			httpGet.setConfig(requestConfig);
			// 执行get请求得到返回对象
			response = httpClient.execute(httpGet);
			// 通过返回对象获取返回数据
			HttpEntity entity = response.getEntity();
			// 通过EntityUtils中的toString方法将结果转换为字符串
			result = EntityUtils.toString(entity);
		} catch (ClientProtocolException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			// 关闭资源
			if (null != response) {
				try {
					response.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			if (null != httpClient) {
				try {
					httpClient.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
		return result;
	}


	/**
	 * post请求
	 * @param url 请求地址
	 * @param paramMap 携带参数
	 * @return
	 */
	public static String doPost(String url, Map<String, Object> paramMap) {
		CloseableHttpClient httpClient = null;
		CloseableHttpResponse httpResponse = null;
		String result = "";
		// 创建httpClient实例
		httpClient = HttpClients.createDefault();
		// 创建httpPost远程连接实例
		HttpPost httpPost = new HttpPost(url);
		// 配置请求参数实例
		RequestConfig requestConfig = RequestConfig.custom().setConnectTimeout(35000)// 设置连接主机服务超时时间
				.setConnectionRequestTimeout(35000)// 设置连接请求超时时间
				.setSocketTimeout(60000)// 设置读取数据连接超时时间
				.build();
		// 为httpPost实例设置配置
		httpPost.setConfig(requestConfig);
		// 设置请求头
		httpPost.addHeader("Content-Type", "application/x-www-form-urlencoded");
		// 封装post请求参数
		if (null != paramMap && paramMap.size() > 0) {
			List<NameValuePair> nvps = new ArrayList<NameValuePair>();
			// 通过map集成entrySet方法获取entity
			Set<Entry<String, Object>> entrySet = paramMap.entrySet();
			// 循环遍历,获取迭代器
			Iterator<Entry<String, Object>> iterator = entrySet.iterator();
			while (iterator.hasNext()) {
				Entry<String, Object> mapEntry = iterator.next();
				nvps.add(new BasicNameValuePair(mapEntry.getKey(), mapEntry.getValue().toString()));
			}

			// 为httpPost设置封装好的请求参数
			try {
				httpPost.setEntity(new UrlEncodedFormEntity(nvps, "UTF-8"));
			} catch (UnsupportedEncodingException e) {
				e.printStackTrace();
			}
		}
		try {
			// httpClient对象执行post请求,并返回响应参数对象
			httpResponse = httpClient.execute(httpPost);
			// 从响应对象中获取响应内容
			HttpEntity entity = httpResponse.getEntity();
			result = EntityUtils.toString(entity);
		} catch (ClientProtocolException e) {
			e.printStackTrace();
			return null;
		} catch (IOException e) {
//			e.printStackTrace();
			return null;
		} finally {
			// 关闭资源
			if (null != httpResponse) {
				try {
					httpResponse.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			if (null != httpClient) {
				try {
					httpClient.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
		return result;
	}



	/**
	 * 将返回结果封装为list便于使用
	 * @param result 接口返回值
	 * @return
	 */
	public static List<Map<String,Object>> getMapList(String result){
		JSONArray array = JSONArray.parseArray(result);
		List<Map<String,Object>> resultList = new ArrayList<>();
		if(array!=null && array.size()>0){
			for(int i = 0;i<array.size();i++){
				Map<String, Object> obj = (Map<String, Object>)array.get(i);
				resultList.add(obj);
			}
		}
		return resultList;
	}



	/**
	 * @param paramMap 参数集合
	 * @param url      远程数据接口url
	 * @return
	 * @author luhui
	 * @date 2016年11月23日 下午4:12:18
	 * @description 根据参数和url获取远程接口数据
	 */
	@SuppressWarnings("unchecked")
	public static Map<String, Object> getResponseResult(Map<String, Object> paramMap, String url) {
		Map<String, Object> resMap = new HashMap<String, Object>();
		String resResult = getResponseResultStr(paramMap, url);
		ObjectMapper mapper = new ObjectMapper();
		log.info("开始转换成MAP......");
		try {
//			resMap = mapper.readValue(resResult, Map.class);
			resMap = mapper.readValue(resResult,Map.class);
			log.info("转换成MAP成功......");
		} catch (IOException e) {
			e.printStackTrace();
			log.info("转换成MAP失败......>>>>" + e);
		}
		return resMap;
	}



	/**
	 * @param paramMap
	 * @param url
	 * @return String
	 * 创 建 人：luhui
	 * 创建时间:2017年5月12日 上午10:05:20
	 * 修 改 人：luhui
	 * 修改时间:2017年5月12日 上午10:05:20
	 * @Title: getResponseResultStr
	 * @Description: 获取响应的字符串结果
	 * @since 1.0.0
	 */
	public static String getResponseResultStr(Map<String, Object> paramMap, String url) {
		CloseableHttpClient httpclient = HttpClients.createDefault();
		HttpPost httpPost = new HttpPost(url);

		List<NameValuePair> nvps = getNameValuePairListByMapParam(paramMap);

		String resResult = "";
		try {
			if (null != nvps && nvps.size() > 0) {
				httpPost.setEntity(new UrlEncodedFormEntity(nvps, "UTF-8"));
				//httpPost.setHeader(, value);
				log.info("开始请求远程接口数据......");
				CloseableHttpResponse response = httpclient.execute(httpPost);
				int status = response.getStatusLine().getStatusCode();
				if (status >= 200 && status < 300) {
					log.info("远程接口数据响应成功。");
					HttpEntity entity = response.getEntity();
					if (entity != null) {
						log.info("开始解析响应结果......");
						resResult = EntityUtils.toString(entity, "UTF-8");
						log.info("--------------------------------------");
						log.info("Response content: " + resResult);
						log.info("--------------------------------------");


						log.info("解析响应结果完成。");
					}
				}
			}

		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
			log.error(e.toString());
		} catch (ClientProtocolException e) {
			e.printStackTrace();
			log.error(e.toString());
		} catch (IOException e) {
			e.printStackTrace();
			log.error(e.toString());
		} finally {
			try {
				log.info("开始关闭httpclient......");
				httpclient.close();
				log.info("关闭httpclient成功。");
			} catch (IOException e) {
				e.printStackTrace();
				log.error("关闭异常:" + e);
			}
		}


		return resResult;
	}



	/**
	 * @param paramMap
	 * @return
	 * @author luhui
	 * @date 2016年11月23日 下午4:11:26
	 * @description 根据参数获取httpclient的参数类型NameValuePair
	 */
	public static List<NameValuePair> getNameValuePairListByMapParam(Map<String, Object> paramMap) {
		List<NameValuePair> nvps = new ArrayList<NameValuePair>();
		Set<String> set = paramMap.keySet();
		Iterator<String> it = set.iterator();
		while (it.hasNext()) {
			String key = it.next();
			String value = (String) paramMap.get(key);
			nvps.add(new BasicNameValuePair(key, value));
		}
		return nvps;
	}

}
